package com.crcode.crm.service.role.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.crcode.crm.bean.module.ModuleBean;
import com.crcode.crm.bean.role.RoleBean;
import com.crcode.crm.bean.role.RoleModuleBean;
import com.crcode.crm.bean.role.RoleUserBean;
import com.crcode.crm.bean.user.UserBean;
import com.crcode.crm.dao.role.RoleDao;
import com.crcode.crm.service.module.ModuleService;
import com.crcode.crm.service.role.RoleModuleService;
import com.crcode.crm.service.role.RoleService;
import com.crcode.crm.service.role.RoleUserService;
import com.crcode.crm.utils.DateUtil;
import com.crcode.crm.utils.PageVo;
import com.crcode.crm.utils.ResultPageUtil;
import com.crcode.crm.utils.ResultUtil;

/**
 * 角色管理业务逻辑实现层
 * 
 * @author lxw
 * @date 2018年4月1日 下午1:52:39
 * @version V1.0
 */
@Service(value="roleService")
@Transactional
public class RoleServiceImpl implements RoleService {

	@Autowired
	private RoleDao roleDao;
	@Autowired
	private ModuleService moduleService;
	@Autowired
	private RoleUserService roleUserService;
	@Autowired
	private RoleModuleService roleModuleService;
	@Autowired
	private JdbcTemplate jdbc;
	@Override
	public RoleBean getById(Integer serializable) {

		return this.roleDao.findById(serializable).get();
	}

	@Override
	public RoleBean saveResultBean(RoleBean t) {

		return this.roleDao.save(t);
	}

	@Override
	public boolean saveResultBoolean(RoleBean t) {
		try {
			this.roleDao.save(t);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public RoleBean updateResultBean(RoleBean t) {
		
		return this.roleDao.save(t);
	}

	@Override
	public boolean updateResultBoolean(RoleBean t) {
		
		try {
			this.roleDao.save(t);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public boolean delete(Integer serializable) {
		try {
			this.roleDao.deleteById(serializable);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public List<RoleBean> getAll() {

		return this.roleDao.findAll();
	}

	@Override
	public ResultPageUtil findAll(RoleBean role, PageVo vo) {
		
		Integer pageIndex = vo.getPageIndex() - 1;
		Pageable pageable =null;
		if(StringUtils.isNotEmpty(vo.getOrderBy())){
			if(vo.getOrderDesc()==1){
				pageable =PageRequest.of(pageIndex, vo.getPageSize(),Direction.DESC, vo.getOrderBy());
			}else if(vo.getOrderDesc()==0){
				pageable = PageRequest.of(pageIndex, vo.getPageSize(),Direction.ASC, vo.getOrderBy());
			}	
		}else{
			pageable = PageRequest.of(pageIndex, vo.getPageSize());
		}
		Page<RoleBean> page = roleDao.findAll(spec(role), pageable);
		ResultPageUtil rpu = new ResultPageUtil();
		rpu.setCurrentPage(vo.getPageIndex());
		rpu.setPageSize(vo.getPageSize());
		rpu.setTotalPages(page.getTotalPages());
		rpu.setRows(page.getContent());
		rpu.setTotal(page.getTotalElements());
		return rpu;
	}
	
	/**
	 * 创建动态查询条件组合
	 * @author lxw  
	 * @date 2018年8月27日 下午2:59:37
	 * @param role
	 * @return
	 */
    private Specification<RoleBean> spec(final RoleBean role) {
        Specification<RoleBean> spec = new Specification<RoleBean>() {
			private static final long serialVersionUID = 1L;

			@Override
			public Predicate toPredicate(Root<RoleBean> root, CriteriaQuery<?> criteriaQuery,
					CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<>();
				if (StringUtils.isNotEmpty(role.getRoleName())) {
					predicates.add(cb.like(root.get("roleName"), "%" +role.getRoleName()+ "%"));
				}
				return cb.and(predicates.toArray(new Predicate[predicates.size()]));
			}
		};
        return spec;
    }
    /**
     * 新增保存角色
     */
	@Override
	public ResultUtil addSaveRole(RoleBean role,UserBean user) {
		List<RoleBean> lr = this.roleDao.findByRoleName(role.getRoleName());
		ResultUtil ru = new ResultUtil();
		if(!lr.isEmpty()){
			ru.setInfo("操作失败，角色名称 已存在！");
			ru.setObj(null);
			ru.setStatus(false);
			return ru;
		}
		role.setUuid(UUID.randomUUID().toString().replaceAll("-", ""));
		role.setCreateTime(DateUtil.DateToStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
		role.setCreatorName(user.getUserRealName());
		boolean is = this.saveResultBoolean(role);
		ru.setInfo(is?"操作成功！":"操作失败！");
		ru.setObj(role);
		ru.setStatus(is);
		return ru;
	}
	/**
	 * 编辑保存角色
	 */
	@Override
	public ResultUtil editSaveRole(RoleBean role) {
		List<RoleBean> lr = this.roleDao.findByRoleNameAndUuidNot(role.getRoleName(),role.getUuid());
		ResultUtil ru = new ResultUtil();
		if(!lr.isEmpty()){
			ru.setInfo("操作失败，角色名称 已存在！");
			ru.setObj(null);
			ru.setStatus(false);
			return ru;
		}
		RoleBean oldR = this.roleDao.findByUuid(role.getUuid()); 
		oldR.setIsUse(role.getIsUse());
		oldR.setRoleName(role.getRoleName());
		oldR.setRoleRemark(role.getRoleRemark());
		boolean is = this.saveResultBoolean(oldR);
		ru.setInfo(is?"操作成功！":"操作失败！");
		ru.setObj(oldR);
		ru.setStatus(is);
		return ru;
	}

	@Override
	public List<RoleBean> getRoleByIsUse(Integer isUse) {

		return this.roleDao.findByIsUse(isUse);
	}

	@Override
	public List<RoleBean> getRolesByUuids(List<String> uuids) {

		return this.roleDao.findByUuidIn(uuids);
	}

	@Override
	public boolean deleteByRoleUuidsIn(List<String> uuids) {
		try {
			this.roleDao.deleteByUuidIn(uuids);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	@Override
	public ResultUtil changeRoleIsUse(String uuids, Integer isUse) {

		String [] arr = uuids.split(",");
		List<String> luuids = Arrays.asList(arr);
		List<RoleBean> olr = this.roleDao.findByUuidIn(luuids);
		List<RoleBean> nlr = new ArrayList<>();
		for (RoleBean role : olr) {
			role.setIsUse(isUse);
			nlr.add(role);
		}
		boolean is = false;
		try {
			this.roleDao.saveAll(nlr);
			is = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		ResultUtil ru = new ResultUtil();
		ru.setInfo(is?"操作成功！":"操作失败！");
		ru.setObj(null);
		ru.setStatus(is);
		return ru;
	}

	@Override
	public ResultUtil deleteRoleByUuids(String uuids) {
		
		ResultUtil ru = new ResultUtil();
		
		String [] arr = uuids.split(",");
		List<String> luuids = Arrays.asList(arr); 
		boolean is = false;
		is = this.roleModuleService.deleteByRoleUuidIn(luuids);
		if(!is){
			ru.setInfo("操作失败！");
			ru.setObj(uuids+"删除模块关联数据失败，请查验！");
			ru.setStatus(is);
			return ru;
		}
		is = this.roleUserService.deleteByRoleUuidIn(luuids);
		if(!is){
			ru.setInfo("操作失败！");
			ru.setObj(uuids+"删除用户关联数据失败，请查验！");
			ru.setStatus(is);
			return ru;
		}
		try {
			this.roleDao.deleteByUuidIn(luuids);
			is = true;
		} catch (Exception e) {
			e.printStackTrace();
			is = false;
		}
		ru.setInfo(is?"操作成功！":"操作失败！");
		ru.setObj(null);
		ru.setStatus(is);
		return ru;
	}

	@Override
	public Map<String, Object> findRolePowerByUuid(String uuid) {
		Map<String, Object> map = new HashMap<String, Object>();
		RoleBean role = roleDao.findByUuid(uuid);
		map.put("role", role);
		Map<String, Object> moduleMap = createModuleTree(role.getUuid());
		map.put("module", moduleMap);
		Map<String, Object> userMap = createUserTree(role.getUuid());
		map.put("user", userMap);
		return map;
	}
	
	/**
	 * 编辑角色创建模块树形数据
	 * @author lxw
	 * @date 2019年1月22日
	 * @param roleUuid
	 * @return
	 */
	public Map<String, Object> createModuleTree(String roleUuid) {

		Map<String, Object> rm = new HashMap<String, Object>();
		rm.put("id", 0);
		rm.put("uuid", 0);
		rm.put("name", "根节点");
		rm.put("puuid", 0);
		rm.put("level", 0);
		String sql = "select count(*) as co from sys_role_module where role_uuid =? ";
		Map<String, Object> co = jdbc.queryForMap(sql, roleUuid);
		if (co.get("co").toString().equals("0")) {
			rm.put("checked", false);
		} else {
			rm.put("checked", true);
		}
		rm.put("children", createModuleAllSubset("0", roleUuid));
		return rm;
	}

	/**
	 * 创建模块子集
	 * @author lxw
	 * @date 2019年1月22日
	 * @param puuid
	 * @param roleUuid
	 * @return
	 */
	public List<Map<String, Object>> createModuleAllSubset(String puuid, String roleUuid) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		List<ModuleBean> ilist = moduleService.getDataByModuleTyoeAndPuuid(0,puuid);
		if (ilist.isEmpty()) {
			return null;
		}
		for (ModuleBean m : ilist) {
			Map<String, Object> rm = new HashMap<String, Object>();
			rm.put("id", m.getId());
			rm.put("uuid", m.getUuid());
			rm.put("name", m.getModuleName());
			rm.put("puuid", m.getPuuid());
			rm.put("level", m.getModuleLevel());
			String sql = "select count(*)as co from sys_role_module where role_uuid =? and module_uuid = ? ";
			Map<String, Object> co = jdbc.queryForMap(sql, roleUuid, m.getUuid());
			if (co.get("co").toString().equals("0")) {
				rm.put("checked", false);
			} else {
				rm.put("checked", true);
			}
			rm.put("children", createModuleAllSubset(m.getUuid(), roleUuid));
			list.add(rm);
		}
		return list;
	}
	/**
	 * 创建用户树
	 * @author lxw
	 * @date 2019年3月25日
	 * @param roleUuid 角色UUID
	 * @return
	 */
	public Map<String, Object> createUserTree(String roleUuid){
		Map<String, Object> rm = new HashMap<String, Object>();
		rm.put("id", 0);
		rm.put("uuid", 0);
		rm.put("name", "根节点");
		String sql = "select id,uuid,user_real_name as name from sys_user where is_use=1 and login_name <> 'admin'";
		List<Map<String, Object>> users = this.jdbc.queryForList(sql);
		for (Map<String, Object> map : users) {
			map.put("children", null);
			sql = "select count(*) as co from sys_role_user where user_uuid =? and role_uuid=?";
			Map<String, Object> co = jdbc.queryForMap(sql, map.get("uuid"),roleUuid);
			if (co.get("co").toString().equals("0")) {
				map.put("checked", false);
			} else {
				map.put("checked", true);
			}
		}
		rm.put("children", users);
		System.out.println(JSONObject.toJSONString(rm));
		return rm;
	}
	@Override
	public ResultUtil changePower(String roleUuid, String moduleUuids, String userUuids) {

		ResultUtil r = new ResultUtil();
		RoleBean role = roleDao.findByUuid(roleUuid);
		boolean is = false;
		List<String> roleUuids = new ArrayList<>();
		roleUuids.add(roleUuid);
		is = this.roleModuleService.deleteByRoleUuidIn(roleUuids);
		if (moduleUuids.trim().length() > 0) {
			List<RoleModuleBean> rms = new ArrayList<>();
			String[] m = moduleUuids.split(",");
			for (String st1 : m) {
				RoleModuleBean rm = new RoleModuleBean();
				rm.setRoleUuid(roleUuid);
				rm.setModuleUuid(st1);
				rms.add(rm);
			}
			is = this.roleModuleService.batchSaveResultBoolean(rms);
		} 
		is = this.roleUserService.deleteByRoleId(roleUuid);
		if (userUuids.trim().length() > 0) {
			List<RoleUserBean> rms = new ArrayList<>();
			String[] m = userUuids.split(",");
			for (String st1 : m) {
				RoleUserBean rm = new RoleUserBean();
				rm.setRoleUuid(roleUuid);
				rm.setUserUuid(st1);
				rms.add(rm);
			}
			is = this.roleUserService.beathSaveResultBoolean(rms);
		} 
		r.setObj(role);
		r.setInfo(is ? "分配权限成功！" : "分配权限失败！");
		r.setStatus(is ? true : false);
		return r;
	}

	@Override
	public List<Map<String, Object>> findPowerByUser(UserBean user) {
		String sql1 = "";
		if (user.getLoginName().toLowerCase().equals("admin")) {
			sql1 = "select uuid as moduleUuid from sys_module where module_type = 0";
		} else {
			sql1 = "select uuid as moduleUuid from sys_module where module_type = 0 and uuid in ("
					+ "select distinct (module_uuid) from sys_role_module where role_uuid in("
					+ "select distinct(role_uuid)  from sys_role_user where user_uuid = '" + user.getUuid() + "')"
					+ " and role_uuid in(select uuid from sys_role where is_use =1))";
		}

		List<Map<String, Object>> moduleIds = jdbc.queryForList(sql1);
		if (moduleIds.isEmpty()) {
			return new ArrayList<Map<String, Object>>();
		}
		List<String> ml = new ArrayList<String>();
		for (Map<String, Object> map2 : moduleIds) {
			ml.add(map2.get("moduleUuid").toString());
		}

		return createAllSubset("0", ml);
	}
	/**
	 * 创建菜单
	 * @author lxw
	 * @date 2019年1月22日
	 * @param puuid
	 * @param ml
	 * @return
	 */
	public List<Map<String, Object>> createAllSubset(String puuid, List<String> ml) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		List<ModuleBean> ilist = moduleService.getDataByPuuidAndUuidIn(puuid, ml);
		if (ilist.isEmpty()) {
			return list;
		}
		for (ModuleBean m : ilist) {
			Map<String, Object> rm = new HashMap<String, Object>();
			rm.put("id", m.getId());
			rm.put("uuid", m.getUuid());
			rm.put("name", m.getModuleName());
			rm.put("puuid", m.getPuuid());
			rm.put("url", m.getModuleUrl());
			rm.put("icon", m.getIcon());
			rm.put("children", createAllSubset(m.getUuid(), ml));
			list.add(rm);
		}
		return list;
	}
	
	@Override
	public RoleBean getEntityByUuid(String uuid) {

		return this.roleDao.findByUuid(uuid);
	}
	
}